package com.css.fxfzypg.modules.earthquakedisasterloss.repository.Impl;

import com.css.fxfzypg.modules.SettingSeismic.vo.PointVO;
import com.css.fxfzypg.modules.SettingSeismic.vo.SettingSeismicInfluencefliedVO;
import com.css.fxfzypg.modules.earthquakedisasterloss.entity.SeismicInfluenceflyPbe;
import com.css.fxfzypg.modules.earthquakedisasterloss.entity.SettingSeismicInfluenceflied;
import com.css.fxfzypg.modules.earthquakedisasterloss.repository.SettingSeismicInfluencefliedRepository;
import com.css.fxfzypg.modules.earthquakedisasterloss.vo.SeismicInfluencefliedVO;
import com.css.fxfzypg.modules.maps.service.TaskRegionMapService;
import com.css.fxfzypg.util.JdbcUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Description: fxfzypg
 * @Author: lhl
 * @CreateDate: 2022/10/16 17:42
 */
@Repository
public class SettingSeismicInfluencefliedRepositoryImpl implements SettingSeismicInfluencefliedRepository {

    private static final Logger log = LoggerFactory.getLogger(SettingSeismicInfluencefliedRepositoryImpl.class);
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Resource
    TaskRegionMapService taskRegionMapService;
    public static final int BATCH_SIZE = 5000;

    @Override
    public int saveSettingSeismicInfluenceflied(SettingSeismicInfluenceflied entity) {
        //处理空间数据，判断存在自相交则获取修复后的空间数据，否则返回原空间数据wkt
        String geomText = taskRegionMapService.getGeomValidWkt(entity.getGeom());
        entity.setGeom(geomText);
        String sql = "insert into setting_seismic_influenceflied(uuid,earthquake_level,dz_intensity,long_x,short_y," +
                "geom,data_source,remark,task_id,source_earthquake_id,assess_user_id,assess_user_dept,assess_time)" +
                "values (:uuid,:earthquakeLevel,:dzIntensity,:longX,:shortY,ST_GeometryFromText(:geom,4490)," +
                ":dataSource,:remark,:taskId,:sourceEarthquakeId,:assessmentUserId,:assessmentUserDept,:assessmentTime)";
        SqlParameterSource source = new BeanPropertySqlParameterSource(entity);
        //拿到新插入的主键值（i）
        KeyHolder keyHolder = new GeneratedKeyHolder();
        int i = namedParameterJdbcTemplate.update(sql, source, keyHolder);
        return i;
    }

    @Override
    public List<SettingSeismicInfluenceflied> findByTaskId(String taskId) {
        String sql = "select * from setting_seismic_influenceflied where task_id = ?";
        List<SettingSeismicInfluenceflied> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SettingSeismicInfluenceflied.class), taskId);
        return list;
    }

    @Override
    public Integer findCountByTaskId(String taskId) {
        try {
            String sql = "select count(1) from setting_seismic_influenceflied where task_id = ?";
            return jdbcTemplate.queryForObject(sql, Integer.class, taskId);
        } catch (DataAccessException e) {
            return 0;
        }
    }

    @Override
    public int saveSeismicInfluenceflyPbe(SeismicInfluenceflyPbe entity) {
        String sql = "insert into seismic_influencefly_pbe(uuid,influencefly_id,details_id,geom,task_id)" +
                "values(:uuid,:influenceflyId,:detailsId,ST_GeometryFromText(:geom,4490),:taskId)";

        SqlParameterSource source = new BeanPropertySqlParameterSource(entity);
        //拿到新插入的主键值（i）
        KeyHolder keyHolder = new GeneratedKeyHolder();
        int i = namedParameterJdbcTemplate.update(sql, source, keyHolder);
        return i;
    }

    @Override
    public SeismicInfluenceflyPbe getByDetailsId(String detailsId) {
        String sql = "select * from seismic_influencefly_pbe where details_id='" + detailsId + "'";
        List<SeismicInfluenceflyPbe> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SeismicInfluenceflyPbe.class));
        return query.size() < 1 ? null : query.get(0);
    }

    @Override
    public List<PointVO> getPointVOByTaskId(String taskId) {
        String sql = "select c.longitude,c.latitude,c.macro_position,c.earthquake_level,c.fault_num " +
                "from seismic_influencefly_pbe a left join setting_seismic_details c on a.details_id =c.id " +
                " where a.task_id=? and c.is_delete='0' group by c.longitude,c.latitude,c.macro_position,c.earthquake_level,c.fault_num";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(PointVO.class), taskId);
    }

    @Override
    public List<SeismicInfluencefliedVO> findByPointVO(String taskId, PointVO pointVO) {
        String sql = "select a.details_id earthquakeId,a.influencefly_id influencefliedId,c.longitude,c.latitude," +
                "c.macro_position,c.fault_num,c.earthquake_level,c.angle,b.dz_intensity,b.long_x,b.short_y " +
                "from seismic_influencefly_pbe a left join setting_seismic_influenceflied b on a.influencefly_id=b.uuid" +
                " left join setting_seismic_details c on a.details_id =c.id " +
                " where a.task_id=? and c.is_delete='0' and c.longitude='" + pointVO.getLongitude() + "' and c.latitude='"
                + pointVO.getLatitude() + "' and c.earthquake_level='" + pointVO.getEarthquakeLevel() + "'";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SeismicInfluencefliedVO.class), taskId);
    }

    @Override
    public List<SettingSeismicInfluencefliedVO> findInfluenceflyByTaskId(String taskId) {
        String sql = "select st_astext(b.geom) geomText,b.dz_intensity dzIntensity,C.longitude longitude,C.latitude latitude,C.earthquake_level earthquakeLevel,C.angle angle,b.source_earthquake_id sourceEarthquakeId " +
                "from setting_seismic_details C left join setting_seismic_influenceflied b on c.id=b.source_earthquake_id" +
                " where b.task_id=? and c.is_delete='0'";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SettingSeismicInfluencefliedVO.class), taskId);
    }

    @Override
    public List<SeismicInfluencefliedVO> find3ByTaskId(String taskId) {
        String sql = "select a.influencefly_id influencefliedId,c.fault_num,c.earthquake_level,c.angle " +
                "from seismic_influencefly_pbe a left join setting_seismic_details c on a.details_id =c.id " +
                " where a.task_id=? and c.is_delete='0' order by c.fault_num,c.earthquake_level,c.angle";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SeismicInfluencefliedVO.class), taskId);
    }

    @Override
    public SettingSeismicInfluenceflied findByTaskIdLimit(String taskId) {
        String sql = "select * from setting_seismic_influenceflied where task_id = ? limit 1";
        List<SettingSeismicInfluenceflied> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SettingSeismicInfluenceflied.class), taskId);
        return list.size() < 1 ? null : list.get(0);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveSettingSeismicInfluencefliedList(List<SettingSeismicInfluenceflied> influencefliedList) {
        try {
            String sql = "insert into setting_seismic_influenceflied(uuid,earthquake_level,dz_intensity,long_x,short_y," +
                    "geom,data_source,remark,task_id,source_earthquake_id,assess_user_id,assess_user_dept,assess_time)" +
                    "values (:uuid,:earthquakeLevel,:dzIntensity,:longX,:shortY,ST_GeometryFromText(:geom,4490)," +
                    ":dataSource,:remark,:taskId,:sourceEarthquakeId,:assessmentUserId,:assessmentUserDept,:assessmentTime)";
            namedParameterJdbcTemplate.batchUpdate(sql, SqlParameterSourceUtils.createBatch(influencefliedList));
        } catch (Exception e) {
            throw new RuntimeException("批量插入失败", e);
        }


    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveSeismicInfluenceflyPbeLisst(List<SeismicInfluenceflyPbe> seismicInfluenceflyPbeArgs) {
        try {
            String sql = "insert into seismic_influencefly_pbe(uuid,influencefly_id,details_id,geom,task_id)" +
                    "values(:uuid,:influenceflyId,:detailsId,ST_GeometryFromText(:geom,4490),:taskId)";
            namedParameterJdbcTemplate.batchUpdate(sql, SqlParameterSourceUtils.createBatch(seismicInfluenceflyPbeArgs));
        } catch (Exception e) {
            throw new RuntimeException("批量插入失败", e);
        }
    }

    @Override
    public void createInfluencefliedTable(String taskId) {
        log.info("创建分区表开始-------------------");
        String createSql = "create table setting_seismic_influenceflied_" + taskId +
                " PARTITION OF setting_seismic_influenceflied for values in ('" + taskId + "')";
        JdbcUtil.executeSql(createSql);
        log.info("创建分区表结束--------------------");
    }


}
